package cn.jx.cjm.security.common.handler;

import cn.jx.cjm.security.common.bean.CjmDepartment;
import cn.jx.cjm.security.common.bean.CjmGrantedAuthority;
import cn.jx.cjm.security.common.bean.TokenUser;
import cn.jx.cjm.security.common.util.ResponseUtils;
import cn.jx.cjm.security.entity.SysDepartment;
import cn.jx.cjm.security.entity.SysUserDepartment;
import cn.jx.cjm.security.entity.SysUserRole;
import cn.jx.cjm.security.service.ISysDepartmentService;
import cn.jx.cjm.security.service.ISysRoleService;
import cn.jx.cjm.security.service.ISysUserDepartmentService;
import cn.jx.cjm.security.service.ISysUserRoleService;
import cn.jx.cjm.common.enums.BizExceptionEnum;
import cn.jx.cjm.common.exception.BizException;
import cn.jx.cjm.common.util.JwtTokenUtils;
import cn.jx.cjm.security.common.constant.SecuritySystemConstants;
import cn.jx.cjm.security.entity.SysRole;
import cn.jx.cjm.security.support.SysUserSupportService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 登录成功
 *
 * @author James Chen right_way@foxmail.com
 * @since 2018年10月12日 上午10:02:09
 */
@Component
@Slf4j
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
    @Autowired
    private SysUserSupportService sysUserSupportService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysUserDepartmentService sysUserDepartmentService;
    @Autowired
    private ISysDepartmentService sysDepartmentService;
    @Autowired
    private ResponseUtils responseUtils;



    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {

        //获取登录成功的用户信息
        TokenUser tokenUser = (TokenUser) authentication.getPrincipal();

        //用户是否为顶级管理员
        if (SecuritySystemConstants.SUPER_ADMIN_ID.equals(tokenUser.getId())) {

            CjmGrantedAuthority grantedAuthority = new CjmGrantedAuthority();
            grantedAuthority.setSysRoleId(SecuritySystemConstants.SUPER_ADMIN_ID);
            grantedAuthority.setAuthority("顶级管理员");
            tokenUser.setAuthorities(Collections.singletonList(grantedAuthority));

            CjmDepartment department = new CjmDepartment();
            department.setDepartmentId(null);
            department.setDepartmentName("顶级管理员");
            tokenUser.setDepartments(Collections.singletonList(department));
        } else {
            //用户角色
            QueryWrapper<SysUserRole> roleQueryWrapper = new QueryWrapper<>();
            roleQueryWrapper.eq("sys_user_id", tokenUser.getId());
            List<SysUserRole> sysUserRoleList = sysUserRoleService.list(roleQueryWrapper);
            if (CollectionUtils.isEmpty(sysUserRoleList)) {
                throw new BizException(BizExceptionEnum.AUTH_FORBIDDEN);
            }
            Set<Integer> sysRoleIdSet = sysUserRoleList.stream().map(SysUserRole::getSysRoleId).collect(Collectors.toSet());
            Collection<SysRole> sysRoleList = sysRoleService.listByIds(sysRoleIdSet);
            if (!CollectionUtils.isEmpty(sysRoleList)) {
                List<CjmGrantedAuthority> grantedAuthorities = new ArrayList<>(sysRoleList.size());
                for (SysRole sysRole : sysRoleList) {
                    CjmGrantedAuthority grantedAuthority = new CjmGrantedAuthority();
                    grantedAuthority.setSysRoleId(sysRole.getId());
                    grantedAuthority.setAuthority(sysRole.getAuthority());
                    grantedAuthorities.add(grantedAuthority);
                }
                tokenUser.setAuthorities(grantedAuthorities);
            }

            // 用户部门
            QueryWrapper<SysUserDepartment> departmentQueryWrapper = new QueryWrapper<>();
            departmentQueryWrapper.eq("sys_user_id", tokenUser.getId());
            List<SysUserDepartment> sysUserDepartments = sysUserDepartmentService.list(departmentQueryWrapper);
            if (!CollectionUtils.isEmpty(sysUserDepartments)) {
                Set<Integer> sysDepartmentIdSet = sysUserDepartments.stream().map(SysUserDepartment::getSysDepartmentId).collect(Collectors.toSet());
                Collection<SysDepartment> sysDepartments = sysDepartmentService.listByIds(sysDepartmentIdSet);
                if (!CollectionUtils.isEmpty(sysDepartments)) {
                    List<CjmDepartment> departments = new ArrayList<>(sysDepartments.size());
                    for (SysDepartment sysDepartment : sysDepartments) {
                        CjmDepartment cjmDepartment = new CjmDepartment();
                        cjmDepartment.setDepartmentId(sysDepartment.getId());
                        cjmDepartment.setDepartmentName(sysDepartment.getName());
                        cjmDepartment.setDepartmentRule(sysDepartment.getRule());
                        departments.add(cjmDepartment);
                    }
                    tokenUser.setDepartments(departments);
                }
            }

        }


        //使用jwt生成token
        String authToken = JwtTokenUtils.getJwtString(tokenUser);
        sysUserSupportService.updateLastLoginTime(tokenUser.getId());
        log.info("用户 {} - {} 登入系统!", tokenUser.getUsername(),tokenUser.getRealName());
        tokenUser.setToken(authToken);
        //对前端隐藏密码
        tokenUser.setPassword(null);

        responseUtils.send(request, response, JSON.toJSONString(R.ok(tokenUser)));
    }
}
